package com.fulihui.wgj.admin.api.base;

import com.alibaba.fastjson.JSON;
import com.fulihui.common.builder.web.JsonResultBuilder;
import com.fulihui.common.error.Errors;
import com.fulihui.common.result.web.Result;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 统一日志处理
 *
 * @author: Levon
 * @date: 2018-08-09 18:18
 */
@Component
@Aspect
public class BaseAspectController {

    public static final Logger logger = LoggerFactory.getLogger(BaseAspectController.class);

    @Pointcut("execution(public * com.fulihui.wgj.admin.api..*.*Controller.*(..)) && !execution(public * com.fulihui.wgj.admin.api.base.*Controller.*(..))")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object handleControllerMethod(ProceedingJoinPoint pjp) {
        Stopwatch stopwatch = Stopwatch.createStarted();
        Result<?> apiResponse = null;
        try {
            logger.info("-> 执行方法: {}, -> 参数：{}", pjp.getSignature(), Lists.newArrayList(pjp.getArgs()).toString());
            apiResponse = (Result<?>) pjp.proceed(pjp.getArgs());
            String time = stopwatch.stop().elapsed(TimeUnit.MILLISECONDS) + "ms";
            logger.info("-> 执行结束({}), {}, 返回：{}", time, pjp.getSignature(), printResult(apiResponse));
        } catch (Throwable throwable) {
            apiResponse = handlerException(pjp, throwable);
        }
        return apiResponse;
    }

    private Result<?> handlerException(ProceedingJoinPoint pjp, Throwable e) {
        Result<?> apiResponse = null;
        if (e instanceof RuntimeException) {
            logger.error("RuntimeException: 方法：{}， 参数：{}，异常：{}", pjp.getSignature(), pjp.getArgs(), e.getMessage(), e);
            apiResponse = JsonResultBuilder.fail(Errors.Commons.UNKNOWN_ERROR.getErrcode(), e.getMessage());
        } else {
            logger.error("SystemError: 方法：{}， 参数：{}，异常：{}", pjp.getSignature(), pjp.getArgs(), e.getMessage(), e);
            apiResponse = JsonResultBuilder.fail(Errors.Commons.SYSTEM_ERROR.getErrcode(), e.getMessage());
        }
        return apiResponse;
    }

    private String printResult(Result<?> apiResponse) {
        Result<String> result = new Result();
        if (apiResponse != null) {
            result.setInfo("...");
            result.setCode(apiResponse.getCode());
            result.setMessage(apiResponse.getMessage());
            result.setSuccess(apiResponse.isSuccess());
            return JSON.toJSONString(result);
        }
        return null;
    }
}
